
package com.hd.determine.config.rabbitmq.batch;

import com.google.common.collect.Lists;
import com.hd.common.utils.CollectionUtils;
import com.hd.determine.core.utils.StaticPropUtil;
import com.hd.determine.modules.alarm.model.AlarmDetail;
import com.hd.determine.modules.alarm.service.IAlarmDetailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author chentl
 * @version V1.0
 * @Project 交通运输第三方监测平台
 * @Title AlarmStream.java
 * @Description 报警数据流式处理
 * @Package com.hd.determine.config.rabbitmq.batch
 * @date 2021/3/17 9:14 上午
 * @Copyright: 深圳市宏电技术股份有限公司 All rights reserved.
 */
@Component
@Slf4j
public class AlarmStream {

    /**
     * @Description 报警重入锁
     * @Author chentl
     * @Create: 2021/3/18 8:48 上午
     */
    private Lock alarmLock = new ReentrantLock();

    /**
     * @Description 更新流
     * @Author chentl
     * @Create: 2021/3/16 5:33 下午
     */
    private List<AlarmDetail> updateStream = Lists.newArrayList();


    /**
     * @Description 插入流
     * @Author chentl
     * @Create: 2021/3/16 5:33 下午
     */
//    private List<AlarmDetail> insertStream = Lists.newArrayList();


    @Value("${spring.rabbitmq.batch-size}")
    public Integer batchSize;

    @Resource
    private IAlarmDetailService alarmDetailService;

    /**
     * @return void
     * @author chentl
     * @description 批量流式更新
     * @date 2021/3/17 9:17 上午
     * @params [alarmDetail]
     */
    public void streamUpdate(AlarmDetail alarmDetail) {


        updateStream.add(alarmDetail);


        if (CollectionUtils.isNotEmpty(updateStream) && updateStream.size() >= batchSize) {
            try {
                log.info("[rabbit] 报警更新流已满 {} 条，即将开始批量更新", batchSize);
//                alarmDetailService.multiUpdate(updateStream);


                return;
            } finally {
                updateStream.clear();
            }
        }


        if (StaticPropUtil.SHOW_ALARM_LOG) {
            log.info("[rabbit] 当前更新流大小: {}", updateStream.size());
        }


    }

    /**
     * @return void
     * @author chentl
     * @description 单独写了根据唯一约束检查重复的sql，效率足够，目前暂不用做批量，后续如果产生报警数据的消费能力不够，再考虑此处优化。
     * @date 2021/3/17 9:17 上午
     * @params [alarmDetail]
     */
    public void streamInsert(AlarmDetail alarmDetail) {
        if (Objects.isNull(alarmDetail)) {
            log.error("[determine] 报警对象为 null，跳过生成环节。");
            return;
        }
        alarmDetailService.multiInsert(alarmDetail);
    }


}
